﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Common;

namespace AccessToDataLibrary
{
    public partial class AccessToDataLibrary
    {
        public List<Article> GetAllArticles()
        {
            DataRow[] searchedRows = libraryDataSet.Articles.Select();
            return GetRestPartsOfArticles(searchedRows);
        }

        private List<Article> GetRestPartsOfArticles(DataRow[] searchedRows)
        {
            if (searchedRows == null || searchedRows.Length == 0)
                return null;

            List<Article> articles = new List<Article>();

            foreach (UniversityLibraryDataSet.ArticlesRow articleRow in searchedRows)
            {
                Article article = new Article();
                article.Version = articleRow.Version;

                if (articleRow.ItemsRow != null)
                {
                    article.ID = articleRow.ItemsRow.ID;
                    article.Name = articleRow.ItemsRow.Name;
                    article.Publisher = articleRow.ItemsRow.Publisher;
                    article.PublishedDate = articleRow.ItemsRow.PublishedDate;
                }

                else
                    throw new Exception("Cannot find corresponding Item.");
                if (articleRow.AuthorsRow != null)
                {
                    article.AuthorName = articleRow.AuthorsRow.Name;
                }
                else
                {
                    throw new Exception("Cannot find corresponding Author.");
                }
                 UniversityLibraryDataSet.ArticlesInMagazinesRow[] artInMagRows = articleRow.GetArticlesInMagazinesRows();

                 if (artInMagRows != null && artInMagRows.Length > 0)
                 {
                     foreach (UniversityLibraryDataSet.ArticlesInMagazinesRow artInMagRow in artInMagRows)
                     {
                         article.MagazineIssueNumber = artInMagRow.MagazinesRow.IssueNumber;
                         article.MagazineName = artInMagRow.MagazinesRow.ItemsRow.Name;
                     }
                 }
                 else
                 {
                     throw new Exception("Cannot find corresponding Magazine.");
                 }
                 articles.Add(article);
            }
            return articles;
        }

        public List<Article> GetSearchedArticles(Article searchedArticle)
        {
            UniversityLibraryDataSet.ItemsRow[] searchedItemsRows =
                (UniversityLibraryDataSet.ItemsRow[]) libraryDataSet.Items.Select(MakeFilteredQuery(searchedArticle.ItemFields));

            UniversityLibraryDataSet.AuthorsRow[] searchedAuthorsRows =
                (UniversityLibraryDataSet.AuthorsRow[])libraryDataSet.Authors.Select(MakeFilteredQuery(searchedArticle.AuthorFields));

            if (searchedItemsRows == null || searchedItemsRows.Length == 0 ||
                searchedAuthorsRows == null || searchedAuthorsRows.Length == 0)
                return new List<Article>(0);

            List<UniversityLibraryDataSet.ItemsRow> searchedItemsRowsList =
                searchedItemsRows.ToList<UniversityLibraryDataSet.ItemsRow>();

            List<UniversityLibraryDataSet.ArticlesRow> searchedArticlesRowsList =
                new List<UniversityLibraryDataSet.ArticlesRow>();

            foreach (UniversityLibraryDataSet.ItemsRow itemRow in searchedItemsRowsList)
            {
                UniversityLibraryDataSet.ArticlesRow[] articlesRows = itemRow.GetArticlesRows();

                if (articlesRows != null && articlesRows.Length > 0)
                {
                    searchedArticlesRowsList.Add(articlesRows[0]);
                }
            }

            List<UniversityLibraryDataSet.ArticlesRow> realArticlesRows = new List<UniversityLibraryDataSet.ArticlesRow>();

            for (int i = 0; i < searchedAuthorsRows.Length; i++)
            {
                List<UniversityLibraryDataSet.ArticlesRow> tempsearched =
                    searchedArticlesRowsList.FindAll(val => val.AuthorID == searchedAuthorsRows[i].ID);

                realArticlesRows.AddRange(tempsearched);
            }

            if (realArticlesRows == null && realArticlesRows.Count == 0)
            {
                return new List<Article>(0);
            }
            return GetRestPartsOfArticles(realArticlesRows.ToArray());
        }
        public void AddArticle(List<Article> article_)
        {
            DataRow magazineRow, authorRow;

            foreach (Article article in article_)
            {
                bool canAdd = IsUniqueArticleInDB(article, out magazineRow, out authorRow);
                if (!canAdd)
                {
                    continue;
                }

                // проверяем наличие автора в БД
                UniversityLibraryDataSet.AuthorsRow authorRow_;

                if (authorRow == null)
                    authorRow_ = libraryDataSet.Authors.AddAuthorsRow(Guid.NewGuid(), article.AuthorName);
                else
                    authorRow_ = (UniversityLibraryDataSet.AuthorsRow)authorRow;

                UniversityLibraryDataSet.ItemsRow itemRow =
                    libraryDataSet.Items.AddItemsRow(Guid.NewGuid(), article.Name,
                        article.Publisher, article.PublishedDate);
                UniversityLibraryDataSet.ArticlesRow addedArticleRow =
                    libraryDataSet.Articles.AddArticlesRow(itemRow, authorRow_, article.Version);
                libraryDataSet.ArticlesInMagazines.AddArticlesInMagazinesRow(
                    addedArticleRow, (UniversityLibraryDataSet.MagazinesRow)magazineRow);
            }

            provider.UpdateAllData();
        }

        private bool IsUniqueArticleInDB(Article article, out DataRow magazineRow, out DataRow authorRow)
        {
            magazineRow = null;
            authorRow = null;

            //проверяем существование в БД автора данной статьи

            UniversityLibraryDataSet.AuthorsRow[] authorsRows =
                (UniversityLibraryDataSet.AuthorsRow[])libraryDataSet.Authors.Select(
                "Name = '"+article.AuthorName+"'");

            if (authorsRows != null && authorsRows.Length > 0)
                authorRow = authorsRows[0];
            // проверяем в данном номере журнала существование добавляемой статьи вытягиваем из таблицы items журналы с данным названием
            //т.е. все выпуски данного журнала

            UniversityLibraryDataSet.ItemsRow[] itemsRows =
                (UniversityLibraryDataSet.ItemsRow[])libraryDataSet.Items.Select(
                "Name ='"+article.MagazineName+"'");
            // если нет журнала, то куда мы патаемся добавить статью?

            if (itemsRows == null || itemsRows.Length == 0)
                return false;


            foreach (UniversityLibraryDataSet.ItemsRow itemRow in itemsRows)
            {
                //вытигиваем данные журнала из таблицы magazines

                UniversityLibraryDataSet.MagazinesRow[] magazinesRows =
                    itemRow.GetMagazinesRows();

                if (magazinesRows == null || magazinesRows.Length == 0)
                {
                    throw new Exception("Cannot find corresponding Item.");
                }

                if (magazinesRows[0].IssueNumber != article.MagazineIssueNumber)
                {
                    continue;
                }

                // если данный номер данного журнала всё таки существуеи - это уже хорошо.
                // значит статью можно добавлять если такой статьи в данном номер данного журнала ещё нет.

                magazineRow = magazinesRows[0]; // получили ссылку на строку требуемого номера журнала

                UniversityLibraryDataSet.ArticlesInMagazinesRow[] artInMagRows =
                    magazinesRows[0].GetArticlesInMagazinesRows();

                // перебираем все статьи в данном номере журнала и проверяем их названия
                foreach (UniversityLibraryDataSet.ArticlesInMagazinesRow artInMagRow in artInMagRows)
                {
                    if (article.Name == artInMagRow.ArticlesRow.ItemsRow.Name)
                    {
                        return false;
                    }
                    
                }
                return true;
            }

            return true;
        }


    }
}
